package com.github.baichuan.gb32960;

import com.github.baichuan.binary.digest.CheckSum;
import com.github.baichuan.iot.protocol.datagram.DatagramCodec;
import com.github.baichuan.iot.protocol.datagram.DatagramContext;
import com.github.baichuan.iot.protocol.datagram.DatagramException;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.zip.Checksum;

/**
 * GB32960协议报文编码器
 */
public class ProtocolCodec implements DatagramCodec {
    private final static byte[] HEADER = new byte[] {0x23, 0x23};

    /**
     * 报文解码
     * @param buf 拆包后的报文
     */
    @Override
    public DatagramContext decode(ByteBuf buf) {
        DatagramContext context = new DatagramContext();

        byte[] bytes = ByteBufUtil.getBytes(buf);
        context.setDatagram(bytes);

        byte[] word = new byte[2];
        buf.readBytes(word);
        if(!Arrays.equals(word, HEADER)){
            throw new DatagramException("Datagram header expert 0x230x23, but " + ByteBufUtil.hexDump(word) + " is illegal.");
        }

        // 命令标识
        context.setCmd(buf.readUnsignedByte());
        // 应答标志
        context.putAttribute("respondFlag", buf.readUnsignedByte());
        // 唯一标识码
        context.setDevice(buf.readCharSequence(17, StandardCharsets.US_ASCII).toString());
        // 数据单元加密方式
        context.putAttribute("encryption", buf.readUnsignedByte());

        // 数据单元长度
        int length = buf.readUnsignedShort();
        byte[] payload = new byte[length];
        buf.readBytes(payload);
        context.setCmdPayload(payload);

        // 校验码
        byte bbc = buf.readByte();
        byte[] checkBytes = CheckSum.BBC.check(bytes, 0, bytes.length - 1);
        if(checkBytes[0] != bbc){
            throw new DatagramException("Datagram " + ByteBufUtil.hexDump(bytes) + " bbc check error");
        }

        return context;
    }

    @Override
    public ByteBuf encode(DatagramContext datagramContext) {
        return null;
    }
}
